﻿using System;
using System.Collections.Generic;
using System.Text;
using TTEngine.TTMath;


namespace TTEngine.Graphics
{
    public class AnimatedImage : IAnimatedImage
    {
        public void AddFrame(IImageFrame frame)
        {
            this.frames.Add(frame);
        }
        List<IImageFrame> frames = new List<IImageFrame>();
        public IImageFrame this[int index]
        {
            get
            {
                return frames[index];
            }
        }

        public int FrameCount

        { get { return frames.Count; } }
    }

    public class ImageFrameData : ImageData, IImageFrame
    {
        public ImageFrameData(uint width, uint height, ImageFormat type, int _delay)
            : base(width, height, type)
        {

            this.DelayInMs = _delay;
        }
        public int DelayInMs
        {
            get;
            private set;
        }
    }
    public class ImageData : IImage
    {
        public ImageData(uint width, uint height, ImageFormat type)
        {
            this.Width = width;
            this.Height = height;
            this.Type = type;
            this.data = new byte[width * height * pixelSize];
        }
        public uint Width
        {
            get;
            private set;
        }
        public uint Height
        {
            get;
            private set;
        }
        public int pixelSize
        {
            get
            {
                return Type == ImageFormat.Gray ? 1 : 4;
            }
        }
        public ImageFormat Type
        {
            get;
            private set;
        }
        public byte[] GetData()
        {
            return data;
        }
        public void SetData(byte[] data)
        {
            for (var i = 0; i < this.data.Length; i++)
            {
                this.data[i] = data[i];
            }
        }
        public unsafe void SetData(byte* data)
        {
            for (var i = 0; i < this.data.Length; i++)
            {
                this.data[i] = data[i];
            }
        }
        private byte[] data;
        public byte GetGray(int x, int y)
        {
            if (this.Type != ImageFormat.Gray)
                throw new Exception("error format.");
            return data[y * Width + x];
        }
        public void SetGray(int x, int y, byte gray)
        {
            if (this.Type != ImageFormat.Gray)
                throw new Exception("error format.");
            data[y * Width + x] = gray;
        }
        public Color32 GetRGBA(int x, int y)
        {
            if (this.Type != ImageFormat.RGBA)
                throw new Exception("error format.");
            var index = (y * Width + x) * 4;
            var c = new Color32();
            c.r = data[index];
            c.g = data[index + 1];
            c.b = data[index + 2];
            c.a = data[index + 3];
            return c;
        }
        public void SetRGBA(int x, int y, Color32 color)
        {
            if (this.Type != ImageFormat.RGBA)
                throw new Exception("error format.");
            var index = (y * Width + x) * 4;
            data[index] = color.r;
            data[index + 1] = color.g;
            data[index + 2] = color.b;
            data[index + 3] = color.a;
        }
        public void CopyTo(ImageData target, int x, int y)
        {
            if (target.Type != Type)
            {
                throw new ArgumentException("use Conv");
            }

            int len = this.Type == ImageFormat.RGBA ? 4 : 1;
            for (var srcy = 0; srcy < Height; srcy++)
            {
                for (var srcx = 0; srcx < Width; srcx++)
                {
                    var targetx = srcx + x;
                    var targety = srcy + y;
                    if (targetx < 0 || targetx >= target.Width) continue;
                    if (targety < 0 || targety >= target.Height) continue;
                    if (len == 1)
                    {
                        target.SetGray(targetx, targety, GetGray(srcx, srcy));
                    }
                    else
                    {
                        target.SetRGBA(targetx, targety, GetRGBA(srcx, srcy));
                    }
                }
            }

        }
    }
}
